package sundun.sharding.scaner;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import sundun.sharding.annotation.ExecuteMethodMark;

import java.lang.reflect.Method;
@ConditionalOnProperty(prefix = "sharding.migration", name = "enabled", havingValue = "true", matchIfMissing = true)
@Component
@Slf4j
public class SourceModelScaner implements BeanPostProcessor, InitializingBean {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 由于代理类不会继承原始类上的方法注解，获取最终的目标类
        Class<?> aClass = AopProxyUtils.ultimateTargetClass(bean);
        Method[] methods = aClass.getMethods();

        for (Method method : methods) {
            ExecuteMethodMark executeMethodMark = method.getAnnotation(ExecuteMethodMark.class);
            if (null == executeMethodMark) {
                continue;
            }
            Invoker invoker = Invoker.valueOf(executeMethodMark.value(), method, bean);
            InvokerManager.addInvoker(executeMethodMark.value(), invoker);
            log.info("添加目标方法执行标识: {}", executeMethodMark.value());
        }
        return bean;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("初始化完成===> 目标方法执行处理器");
    }
}
